package com.xxun.xunaddnew;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static android.view.View.GONE;

public class MainActivity extends Activity implements AddFriendsService.OnUpdateShareView {

    private static final String TAG = "MainActivity";
    private static final String COMMON_BT_NAME = "小米";
    private BluetoothAdapter mBluetoothAdapter;

    private XXunBtReceiver xXunBtReceiver;

    private GifView gifView1;
    private TextView mTextView;
    private FrameLayout frameLayout;

    private boolean canTouchable = false;
    private boolean isRegister = false;

    private boolean isNeedReDiscovery = false;
    private Context context;
    /**
     * 处理UI显示
     */
    private Handler myHandler = new Handler() {
        /**
         * Subclasses must implement this to receive messages.
         *
         * @param msg
         */
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.d(TAG, "[myHandler] >> msg: " + msg);
            switch (msg.what) {
                case Constants.MSG_BT_SEARCH_SUCCESS:
                    if (gifView1.isPlaying()) {
                        gifView1.pause();
                        gifView1.setVisibility(GONE);
                    }
                    mTextView.setVisibility(View.VISIBLE);
                    mTextView.setText(R.string.add_reslut_success);
                    canTouchable = false;
                    break;

                case Constants.MSG_BT_SEARCH_FAIL:
                    if (gifView1.isPlaying()) {
                        gifView1.pause();
                        gifView1.setVisibility(GONE);
                    }
                    mTextView.setVisibility(View.VISIBLE);
                    mTextView.setText(Constants.add_result_fail);

                    Log.d(TAG, "[myHandler] >> time out 30s, stop all job, wait for user's order.");

                    isNeedReDiscovery = false;//已经超时，避免后台仍然在搜索蓝牙，降低功耗
                    canTouchable = true;// 此时可以响应屏幕点击事件，点击后重新搜索
                    uninstallRegister();
                    break;

                case Constants.MSG_BT_ONSEARCHING:
                    gifView1.setVisibility(View.VISIBLE);
                    mTextView.setVisibility(GONE);
                    gifView1.play();
                    canTouchable = false;
                    break;

                default:
                    gifView1.setVisibility(GONE);
                    mTextView.setVisibility(View.VISIBLE);
                    mTextView.setText(R.string.add_result_fail);

                    canTouchable = false;
                    break;

            }
        }
    };
    /**
     * 倒计时30秒，每1秒执行一次onTick
     */
    private CountDownTimer countDownTimer = new CountDownTimer(30 * 1000, 1 * 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            Log.d(TAG, "[CountDownTimer] >> onTick ..");
        }

        @Override
        public void onFinish() {
            Log.d(TAG, "[CountDownTimer] >> onFinish ..");
            Message message = new Message();
            message.what = Constants.MSG_BT_SEARCH_FAIL;
            myHandler.sendMessageDelayed(message, 0);
        }
    };

    @Override

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context = this;

        gifView1 = (GifView) findViewById(R.id.img_anim);

        gifView1.setVisibility(View.VISIBLE);
        gifView1.setGifResource(R.drawable.animation_add_friends);
        gifView1.play();


        mTextView = (TextView) findViewById(R.id.text_result);
        frameLayout = (FrameLayout) findViewById(R.id.frame_all);

        //开启倒计时
        countDownTimer.start();
        doSearch();
    }

    /**
     * Called when the Fragment is visible to the user.  This is generally
     * Activity's lifecycle.
     */
    @Override
    public void onStart() {
        super.onStart();


        Log.d(TAG, "[onStart] >> begin. ");
    }

    @Override
    public void onResume() {
        Log.d(TAG, "[onResume] >> begin. ");
        super.onResume();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "[onDestroy] >> begin.");
        uninstallRegister();
        closeDiscoverableTimeout();
    }

    @Override
    public void onUpdateShareView(Message message) {
        Log.d(TAG, "[onUpdateShareView] >> begin.");
        myHandler.sendMessageDelayed(message, 0);
    }

    private void handleResult(String devName, String devAddr) {
        // 需要做非空判断
        if (devName != null && isContain(devName, COMMON_BT_NAME)) {
            Log.d(TAG, "[handleResult] >> find watch bt, and upload info. and set isNeedReDiscovery false.");
            mBluetoothAdapter.cancelDiscovery();
            uninstallRegister();
            isNeedReDiscovery = false;//不需要再次重新搜索
            Message message = new Message();
            message.what = Constants.MSG_BT_SEARCH_SUCCESS;
            myHandler.sendMessageDelayed(message, 0);

            devAddr = "E3:7B:7B:C4:E7:90"; // for Debug
            Intent intent = new Intent(this, AddFriendsService.class);
            intent.putExtra(Constants.INTENT_BLUEADDR, devAddr);
            startService(intent);
            AddFriendsService.setOnUpdateShareView(this);
        } else {
            Log.d(TAG, "[handleResult] >> do not find watch bt, continue search. and set isNeedReDiscovery true");
            isNeedReDiscovery = true;// 本次搜索结束后，将重新搜索一次
        }
    }

    /**
     * 判断big字符串中是否还有small字符串
     *
     * @param big
     * @param small
     * @return
     */
    private boolean isContain(String big, String small) {
        return big.indexOf(small) != -1;
    }

    /**
     * 开启蓝牙扫描
     */
    private void startDiscoveryBt() {
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
            Log.d(TAG, "[startDiscoveryBt] >> on searching, stop it and create a new one.");
        }
        mBluetoothAdapter.startDiscovery();
    }

    /**
     * 注册监听器
     */
    private void installRegister() {
        Log.d(TAG, "[doRegister] >> begin. ");
        isRegister = true;
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        xXunBtReceiver = new XXunBtReceiver();
        registerReceiver(xXunBtReceiver, intentFilter);
    }

    /**
     * 取消监听器，在退出的时候执行
     */
    private void uninstallRegister() {
        Log.d(TAG, "[uninstallRegister] >> unregisterReceiver & diable BluetoothAdapter");
        if (mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.disable();
        }
        if (isRegister) {
            isRegister = false;
            unregisterReceiver(xXunBtReceiver);
        }
    }

    /**
     * 设置蓝牙可见性
     * 由于不能弹窗，只能通过反射调用被hide的setScanMode()
     * 用这种方法开启的可见性，还有个附件的属性，timeout值并没有起到作用，可见性是一直保持的。
     * 可以通行下面类似的代码进行关闭：@closeDiscoverableTimeout()
     *
     * @param timeout
     */
    private void setBTDiscoverableTimeout(int timeout) {
        try {
            Log.d(TAG, "[setBTDiscoverableTimeout] >>  begin.");
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(mBluetoothAdapter, timeout);
            setScanMode.invoke(mBluetoothAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, 1);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private void closeDiscoverableTimeout() {
        try {
            Log.d(TAG, "[closeDiscoverableTimeout] >>  begin.");
            Method setDiscoverableTimeout = Method.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = Method.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(mBluetoothAdapter, 1);
            setScanMode.invoke(mBluetoothAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE, 1);

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private void doSearch() {

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        //@ step1 打开蓝牙
        //@ step2 注册蓝牙监听器
        //@ step3 开启蓝牙扫描


        //@ step1 打开蓝牙
        // 蓝牙未打开，使用enable()，不需要弹窗，是BLE。低功耗蓝牙
        if (!mBluetoothAdapter.isEnabled()) {
            Intent turnOnBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(turnOnBtIntent, Constants.REQUEST_ENABLE_BT);
//            mBluetoothAdapter.enable();
            Log.d(TAG, "need to enable bt. ");
        }

        //@ step2 注册监听器
        installRegister();

        //@ step3 开启蓝牙扫描
        if (mBluetoothAdapter.isEnabled()) {
            Log.d(TAG, "mBluetoothAdapter.getScanMode():1 " + mBluetoothAdapter.getScanMode());
            setBTDiscoverableTimeout(1000);
            Log.d(TAG, "mBluetoothAdapter.getScanMode():2 " + mBluetoothAdapter.getScanMode());
            startDiscoveryBt();
        }
    }

    public void click_frame_all(View view) {
        if (canTouchable) {
            Log.d(TAG, "[click_frame_all] >> canTouchable is true, " +
                    "user touch the screen, do search again.");
            //开启倒计时
            countDownTimer.start();

            Message message = new Message();
            message.what = Constants.MSG_BT_ONSEARCHING;
            myHandler.sendMessageDelayed(message, 0);

            //开启搜索
            doSearch();
        } else {
            Log.d(TAG, "[click_frame_all] >> canTouchable is false, do nothing.");
        }
    }

    /**
     * 监听器，主要是监听蓝牙的各种状态变化，包括：
     * 蓝牙打开、关闭广播； 蓝牙正在搜索广播； 蓝牙搜索到广播；  蓝牙搜索结束广播
     */
    private class XXunBtReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            Log.d(TAG, "[XXunBtReceiver] >> action: " + action);
            if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                Toast.makeText(context, "search start", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "[XXunBtReceiver] >> bluetooth search begin. ");
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                Toast.makeText(context, "search finishs", Toast.LENGTH_SHORT).show();
                if (isNeedReDiscovery) {
                    Log.d(TAG, "[XXunBtReceiver] >> did not find watch bt, start discovery again.");
                    doSearch();
                }
            } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                Log.d(TAG, "[XXunBtReceiver] >> bluetoothDevice: name " + bluetoothDevice.getName()
                        + " id : " + bluetoothDevice.getAddress());
                handleResult(bluetoothDevice.getName(), bluetoothDevice.getAddress());
            } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                switch (btState) {
                    case BluetoothAdapter.STATE_TURNING_ON:
                        Log.d(TAG, "[XXunBtReceiver] >> bt state turning on. ");
                        break;

                    case BluetoothAdapter.STATE_ON:
                        Log.d(TAG, "[XXunBtReceiver] >> bt state is on.");
                        setBTDiscoverableTimeout(1000);
                        startDiscoveryBt();
                        break;

                    case BluetoothAdapter.STATE_TURNING_OFF:
                        Log.d(TAG, "[XXunBtReceiver] >> bt state is turning off. ");
                        break;

                    case BluetoothAdapter.STATE_OFF:
                        Log.d(TAG, "[XXunBtReceiver] >> bt state is off. ");
                        break;

                }
            }
        }
    }

}
